<script setup>
import { ref } from 'vue'

// 基本列表数据
const fruits = ref([
  { id: 1, name: '苹果', color: '红色' },
  { id: 2, name: '香蕉', color: '黄色' },
  { id: 3, name: '葡萄', color: '紫色' },
  { id: 4, name: '橙子', color: '橙色' },
  { id: 5, name: '草莓', color: '红色' }
])

// 带有嵌套数据的列表
const users = ref([
  { 
    id: 1, 
    name: '张三', 
    hobbies: ['读书', '游泳', '编程'] 
  },
  { 
    id: 2, 
    name: '李四', 
    hobbies: ['音乐', '电影'] 
  },
  { 
    id: 3, 
    name: '王五', 
    hobbies: ['旅行', '摄影', '烹饪', '登山'] 
  }
])

// 动态操作相关数据
const newItem = ref('')
const items = ref([
  { id: 1, text: '学习Vue 3' },
  { id: 2, text: '理解响应式原理' },
  { id: 3, text: '掌握组件通信' }
])

// 添加新项目
const addItem = () => {
  if (newItem.value.trim()) {
    const newId = items.value.length > 0 
      ? Math.max(...items.value.map(item => item.id)) + 1 
      : 1
    items.value.push({
      id: newId,
      text: newItem.value.trim()
    })
    newItem.value = ''
  }
}

// 删除项目
const removeItem = (id) => {
  items.value = items.value.filter(item => item.id !== id)
}

// 编辑项目
const editingId = ref(null)
const editText = ref('')

const startEditing = (item) => {
  editingId.value = item.id
  editText.value = item.text
}

const saveEdit = (id) => {
  const item = items.value.find(item => item.id === id)
  if (item && editText.value.trim()) {
    item.text = editText.value.trim()
  }
  cancelEditing()
}

const cancelEditing = () => {
  editingId.value = null
  editText.value = ''
}
</script>

<template>
  <div class="list-rendering-demo">
    <h2>Vue 3 列表渲染</h2>
    
    <p>使用 v-for 指令可以渲染一个列表。</p>
    
    <p>Vue 会根据数组的每一项渲染对应的 DOM 元素，并且在数组数据变化时，自动更新视图。</p>
    
    <div class="example-section">
      <h3>基本列表渲染</h3>
      <ul>
        <li v-for="fruit in fruits" :key="fruit.id">
          {{ fruit.name }} - {{ fruit.color }}
        </li>
      </ul>
    </div>
    
    <div class="example-section">
      <h3>带索引的列表渲染</h3>
      <ol>
        <li v-for="(fruit, index) in fruits" :key="fruit.id">
          第{{ index + 1 }}项: {{ fruit.name }}
        </li>
      </ol>
    </div>
    
    <div class="example-section">
      <h3>对象属性列表渲染</h3>
      <dl>
        <template v-for="fruit in fruits" :key="fruit.id">
          <dt>{{ fruit.name }}</dt>
          <dd>颜色: {{ fruit.color }}</dd>
        </template>
      </dl>
    </div>
    
    <div class="example-section">
      <h3>嵌套列表渲染</h3>
      <ul>
        <li v-for="user in users" :key="user.id">
          <strong>{{ user.name }}</strong> 的爱好:
          <ul>
            <li v-for="(hobby, index) in user.hobbies" :key="index">
              {{ hobby }}
            </li>
          </ul>
        </li>
      </ul>
    </div>
    
    <div class="example-section">
      <h3>动态列表操作</h3>
      <div class="input-group">
        <input 
          v-model="newItem" 
          placeholder="输入新项目" 
          @keyup.enter="addItem"
        />
        <button @click="addItem">添加</button>
      </div>
      
      <ul>
        <li v-for="item in items" :key="item.id">
          <template v-if="editingId === item.id">
            <input v-model="editText" />
            <button @click="saveEdit(item.id)">保存</button>
            <button @click="cancelEditing">取消</button>
          </template>
          <template v-else>
            {{ item.text }}
            <button @click="startEditing(item)">编辑</button>
            <button @click="removeItem(item.id)">删除</button>
          </template>
        </li>
      </ul>
    </div>
    
    <div class="explanation">
      <h3>关键要点</h3>
      <ul>
        <li><strong>v-for 指令</strong>: 用于渲染列表的关键指令</li>
        <li><strong>Key 属性</strong>: 每个 v-for 元素都需要唯一的 key，帮助 Vue 跟踪节点变化</li>
        <li><strong>避免使用索引作为 key</strong>: 除非列表是静态的，不发生重新排序或过滤</li>
        <li><strong>对象遍历</strong>: 可以使用 v-for 遍历对象的属性</li>
        <li><strong>嵌套列表</strong>: 可以在 v-for 内部再使用 v-for</li>
        <li><strong>响应式更新</strong>: 当数组发生变化时，Vue 会自动更新 DOM</li>
      </ul>
    </div>
  </div>
</template>

<style scoped>
.list-rendering-demo {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.example-section {
  margin-bottom: 30px;
  padding: 20px;
  border: 1px solid #ddd;
  border-radius: 5px;
  background-color: #f9f9f9;
}

.example-section h3 {
  margin-top: 0;
  color: #333;
}

.input-group {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.input-group input {
  flex: 1;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.input-group button {
  padding: 8px 15px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.input-group button:hover {
  background-color: #0056b3;
}

button {
  margin-left: 5px;
  padding: 3px 8px;
  background-color: #28a745;
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
}

button:hover {
  background-color: #218838;
}

button:nth-child(2) {
  background-color: #ffc107;
  color: #212529;
}

button:nth-child(2):hover {
  background-color: #e0a800;
}

button:nth-child(3) {
  background-color: #dc3545;
  color: white;
}

button:nth-child(3):hover {
  background-color: #c82333;
}

.explanation {
  background-color: #e9f7ef;
  padding: 20px;
  border-radius: 5px;
}

.explanation h3 {
  margin-top: 0;
}

.explanation ul {
  padding-left: 20px;
}

.explanation li {
  margin-bottom: 8px;
}

dt {
  font-weight: bold;
}

dd {
  margin-left: 20px;
  margin-bottom: 10px;
}
</style>